package org.example.webdav;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.example.webdav.resources.WebDavResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.WritableResource;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

@Component
public class ConsoleRunner implements CommandLineRunner {

    @Autowired
    private ResourceLoader resourceLoader;

    @Override
    public void run(String... args) throws Exception {
        if (args == null || args.length == 0) return;
        String command = args[0];
        switch (command.toLowerCase()) {
            case "test":
                System.out.println("test ok");
                break;
            case "get-resource":
                if (args.length == 2) getResource(args[1]);
                break;
            case "testwork":
                if (args.length == 3) {
                    testWork(args[1], args[2]);
                    break;
                }
            case "generatecsv":
                if (args.length == 2) {
                    generateCsv(args[1], 10, 1000);
                    break;
                }
            default:
                System.out.println("test|getresource|copy");
        }

    }

    private void testWork(String in, String out) {
        Resource inResource = resourceLoader.getResource(in);
        WritableResource outResource = (WritableResource) resourceLoader.getResource(out);
        System.out.println(String.format("is %s exitst %s", out, outResource.exists()));
        try (ZipInputStream zis = new ZipInputStream(inResource.getInputStream()); OutputStream os = outResource.getOutputStream()) {
            ZipEntry entry = zis.getNextEntry();
            if (entry != null) {
                byte[] buffer = new byte[1024000];
                while (zis.read(buffer) > 0) {
                    Thread.sleep(1000);
                    os.write(buffer);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Copy complete");
    }

    private void generateCsv(String location, int colsCount, int rowsCount) throws IOException {
        WritableResource resource = (WritableResource) resourceLoader.getResource(location);
        OutputStreamWriter osw = new OutputStreamWriter(resource.getOutputStream());
        CSVFormat csvFormat = CSVFormat.EXCEL.builder().setDelimiter(';').setHeader(IntStream.range(0, colsCount).mapToObj(x -> "Field" + x).collect(Collectors.toList()).toArray(String[]::new)).build();
        try (final CSVPrinter printer = new CSVPrinter(osw, csvFormat)) {
            Random random = new Random();
            for (int i = 0; i < rowsCount; i++) {
                printer.printRecord((Object[]) IntStream.range(0, colsCount)
                        .boxed()
                        .map(x -> "Value " + x)
                        .collect(Collectors.toList())
                        .toArray(String[]::new));
            }
        }
        System.out.println("generation complete");
    }

    private void getResource(String location) throws IOException {
        WebDavResource resource = (WebDavResource) resourceLoader.getResource(location);
        System.out.println(resource.contentLength());
    }
}
